package stud.mpgame.physics;

/**
 * ...
 * @author pavel[f.pavel91@gmail.com]
 */
class AABB implements IBody {

	private var left:Int;
	private var right:Int;
	private var bottom:Int;
	private var top:Int;
	
	private var nearestX:Int;
	private var nearestY:Int;
	
	private var shortestVector:Vector2D;
	
	public function new(left:Int, bottom:Int, right:Int, top:Int) {
		this.left = left;
		this.bottom = bottom;
		this.right = right;
		this.top = top;
	}
	
	public function intersect(circle:Circle) {
		//projection x
		//AABB_left = left
		//ABBB_right = rigth
		var circleLeft:Float = circle.x - circle.radius;
		var circleRight:Float = circle.x + circle.radius;
		var x:Float = getMinimalVectorCoordinate(left, right, circleLeft, circleRight);
		if (x == 0)
			return;
		var vectorX:Vector2D = new Vector2D(x, 0);
		//projection y
		//AABB_bottom = bottom
		//AABB_top = top
		var circleBottom:Float = circle.y - circle.radius;
		var circleTop:Float = circle.y + circle.radius;
		var y:Float = getMinimalVectorCoordinate(top, bottom, circleBottom, circleTop);
		if (y == 0)
			return;
		var vectorY:Vector2D = new Vector2D(0, y);
		//temp
		if (Math.abs(x) < Math.abs(y)) { 
			shortestVector = vectorX;
		} else {
			circle.velocity.y = 0;
			shortestVector = vectorY;
		}
		//trace("INTERSECT");
		if (circle.x > right) {
			nearestX = right;
		} else if (circle.x < left) {
			nearestX = left;
		} else {
			circle.move(shortestVector);
			return;
		}
		
		if (circle.y > bottom) {
			nearestY = bottom;
		} else if (circle.y < top) {
			nearestY = top;
		} else {
			circle.move(shortestVector);
			return;
		}
		
		var toNearestPoint:Vector2D = new Vector2D(circle.x - nearestX, circle.y - nearestY);
		var length:Float = toNearestPoint.length();
		if (length > circle.radius)
			return;
		toNearestPoint = toNearestPoint.mul((circle.radius - length) / length);
		circle.move(toNearestPoint);
	}
	
	//todo inline?
	private /*inline*/ function getMinimalVectorCoordinate(left:Float, right:Float, bodyLeft:Float, bodyRight:Float):Float {
		if (bodyLeft >= right || bodyRight <= left)
			return 0;
		if (bodyRight > right) {
			return right - bodyLeft;
		} else if (bodyLeft < left) {
			return  left - bodyRight;
		} else if (right - bodyRight < bodyLeft - left) {
			return right - bodyLeft;
		} else {
			return left - bodyRight;
		}		
	}
	
}